<template>
  <a-modal
    :visible="visible"
    :confirm-loading="confirmLoading"
    :title="title"
    :width="width"
    ok-text="确认保存"
    :mask-closable="false"
    @cancel="onClose"
    @ok="handleSubmit"
  >
    <a-form-model
      ref="formInline"
      style="margin-right: 10px;"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
      :rules="rules"
      :model="formInline"
      @submit="handleSubmit"
    >
      <a-button v-show="false" html-type="submit" />

      <div
        v-for="(element, index) in item"
        v-show="showIf(element)"
        :key="itemKeyOld + '-' + index"
        :style="element.style"
      >
        <div v-if="element.type === 'hidden'">
          element hidden
        </div>

        <!-- 上传一张图片 -->
        <a-form-model-item
          v-else-if="element.type === 'upload-image'"
          :label="element.label"
          :prop="element.key"
          :required="element.required"
          :wrapper-col="element.wrapper ? labelWrapperCol : undefined"
        >
          <a-upload
            name="file"
            list-type="picture-card"
            :show-upload-list="false"
            :before-upload="beforeImageUpload"
            :action="
              $http.PrefixURL + '/file?token=' + $token.getRefreshToken()
            "
            :disabled="uploadImage.loading[element.key]"
            style="margin-bottom: -20px;"
            @change="(info) => handleImageChange(info, element.key)"
          >
            <div v-if="uploadImage.loading[element.key]">
              <a-icon type="loading" />
              <div class="ant-upload-text">
                上传图片
              </div>
            </div>
            <img
              v-else-if="
                uploadImage.one[element.key] &&
                uploadImage.one[element.key].url_800
              "
              :src="uploadImage.one[element.key].url_800"
              style="max-height: 200px; max-width: 200px;"
            />
            <div v-else>
              <a-icon
                :type="uploadImage.loading[element.key] ? 'loading' : 'plus'"
              />
              <div class="ant-upload-text">
                上传图片
              </div>
            </div>
          </a-upload>
        </a-form-model-item>

        <!-- 上传文件 -->
        <a-form-model-item
          v-else-if="element.type === 'upload-list'"
          :label="element.label"
          :prop="element.key"
          :required="element.required"
          :wrapper-col="element.wrapper ? labelWrapperCol : undefined"
        >
          <a-row type="flex" style="margin-bottom: -20px;">
            <template
              v-if="
                uploadImage.list[element.key] &&
                uploadImage.list[element.key].length > 0
              "
            >
              <a-col
                v-for="(item, index) in uploadImage.list[element.key]"
                :key="index"
                style="width: 104px; margin: 4px;"
              >
                <a-card hoverable>
                  <div
                    slot="cover"
                    class="imgDiv"
                    @mouseenter="handleMouseEnter($event)"
                    @mouseleave="handleMouseLeave($event)"
                  >
                    <div class="img-view-operate">
                      <a-popconfirm
                        title="是否删除文件?"
                        ok-text="删除"
                        cancel-text="取消"
                        @confirm="handleDelete(element.key, index)"
                      >
                        <a-icon type="delete" />
                      </a-popconfirm>
                    </div>
                    <img v-if="item.url_800" :src="item.url_800" />
                    <div v-else style="text-align: center; padding-top: 20px;">
                      <a-icon
                        v-if="
                          item.file_extension == '.xlsx' ||
                          item.file_extension == '.xls' ||
                          item.file_extension == '.csv' ||
                          item.file_extension == '.xlsm' ||
                          item.file_extension == '.xlt' ||
                          item.file_extension == '.xltx' ||
                          item.file_extension == '.xltm'
                        "
                        type="file-excel"
                        :style="{ fontSize: '50px', color: '#888' }"
                      />
                      <a-icon
                        v-else-if="item.file_extension == '.pdf'"
                        type="file-pdf"
                        :style="{ fontSize: '50px', color: '#888' }"
                      />
                      <a-icon
                        v-else-if="
                          item.file_extension == '.doc' ||
                          item.file_extension == '.docx'
                        "
                        type="file-word"
                        :style="{ fontSize: '50px', color: '#888' }"
                      />
                      <a-icon
                        v-else
                        type="file"
                        :style="{ fontSize: '50px', color: '#888' }"
                      />
                    </div>
                    <div
                      style="
                        position: absolute;
                        bottom: 0px;
                        width: 80%;
                        margin: 5%;
                        font-size: 12px;
                        text-align: center;
                        line-height: 16px;
                      "
                    >
                      {{ item.file_name }}
                    </div>
                  </div>
                </a-card>
              </a-col>
            </template>
            <a-col style="width: 104px; margin: 4px;">
              <a-upload
                name="file"
                list-type="picture-card"
                :show-upload-list="false"
                multiple
                :disabled="uploadImage.loading[element.key]"
                :action="
                  $http.PrefixURL + '/file?token=' + $token.getRefreshToken()
                "
                @change="(info) => handleFileChange(info, element.key)"
              >
                <div>
                  <a-icon
                    :type="
                      uploadImage.loading[element.key] ? 'loading' : 'plus'
                    "
                  />
                  <div class="ant-upload-text">
                    上传文件
                  </div>
                </div>
              </a-upload>
            </a-col>
          </a-row>
        </a-form-model-item>

        <!-- 分组输入，可以增加多行 -->
        <div v-else-if="element.type === 'array'" style="margin-bottom: 20px;">
          <div style="margin-bottom: 10px;">
            <a-space :size="3">
              <template v-for="(item, index) in element.array">
                <div
                  v-if="index == 0"
                  :key="'array_title_' + element.key + '_' + index"
                  style="width: 30px; margin-right: 6px;"
                ></div>
                <div
                  v-if="showIf(item)"
                  :key="element.type + '_title_' + element.key + '_' + index"
                  :style="{
                    ...item.style,
                    width: item.width,
                  }"
                >
                  {{ item.label }}
                </div>
              </template>
            </a-space>
          </div>

          <div
            v-if="
              !formInline[element.key] || formInline[element.key].length <= 0
            "
            style="margin-bottom: 10px;"
          >
            <a-empty />
          </div>
          <draggable
            :list="formInline[element.key]"
            class="changeGhost"
            ghost-class="ghost"
            handle=".handle"
          >
            <div
              v-for="(arrItem, arrIndex) in formInline[element.key]"
              :key="element.type + '_value_' + element.key + '_' + arrIndex"
              style="margin-bottom: 10px;"
            >
              <a-space :size="3">
                <div style="width: 30px; margin-right: 6px;">
                  <a-popconfirm
                    title="删除选择?"
                    ok-text="确认"
                    cancel-text="取消"
                    class="link"
                    @confirm="deleteArrayItem(element, arrIndex)"
                  >
                    <a-tag color="#108ee9" style="color: #fff;" class="handle">
                      {{ arrIndex + 1 }}
                    </a-tag>
                  </a-popconfirm>
                </div>
                <template v-for="(item, index) in element.array">
                  <div
                    v-if="showIf(item)"
                    :key="
                      element.type +
                      '_value_' +
                      element.key +
                      '_' +
                      arrIndex +
                      '_' +
                      item.key +
                      '_' +
                      index
                    "
                    :style="{
                      ...item.style,
                      width: item.width,
                    }"
                  >
                    <!-- <div v-if="item.type === 'show'">
                      {{ !arrItem[item.key] ? "-" : arrItem[item.key] }}
                    </div> v-else-->

                    <edit
                      v-model="arrItem[item.key]"
                      :element="item"
                      :debug="debug"
                      @change="
                        (...arr) =>
                          elementArrayChange(
                            item,
                            element.key,
                            arrIndex,
                            ...arr
                          )
                      "
                    />
                  </div>
                </template>
              </a-space>
            </div>
          </draggable>

          <div
            v-if="!element.addHideFlag || element.addHideFlag != true"
            style="margin-bottom: 10px; padding-left: 30px;"
          >
            <span
              v-if="formInline[element.key + '_total_str']"
              style="float: right;"
            >
              {{ formInline[element.key + "_total_str"] }}
            </span>
            <a @click="addArrayItem(element.key)">
              <a-icon type="plus" /> 增加一行
            </a>
            <span style="color: #999; margin-left: 10px;">
              点击序号可删除，拖动序号可排序
            </span>
          </div>
        </div>

        <!-- 一行显示多个输入 -->
        <a-form-model-item
          v-else-if="element.type === 'space'"
          :label="element.label"
          :required="element.required"
          :wrapper-col="element.wrapper ? labelWrapperCol : undefined"
        >
          <a-space>
            <template v-for="(elementSec, index) in element.space">
              <span
                v-if="showIf(elementSec)"
                :key="index + '_sec'"
                :style="elementSec.style"
              >
                <a-button
                  v-if="elementSec.type === 'button'"
                  @click="btnClick(elementSec)"
                >
                  {{ elementSec.value }}
                </a-button>

                <edit
                  v-else
                  v-model="formInline[elementSec.key]"
                  :element="elementSec"
                  :debug="debug"
                  :style="{
                    width: elementSec.width,
                  }"
                  @change="(...arr) => elementChange(elementSec, ...arr)"
                />
              </span>
            </template>
          </a-space>
        </a-form-model-item>

        <div v-else-if="element.type === 'editor'">
          <edit
            v-model="formInline[element.key]"
            :element="element"
            :debug="debug"
            @change="(...arr) => elementChange(element, ...arr)"
          />
        </div>

        <a-form-model-item
          v-else
          :label="element.label"
          :prop="element.key"
          :required="element.required"
          :wrapper-col="element.wrapper ? labelWrapperCol : undefined"
        >
          <edit
            v-model="formInline[element.key]"
            :element="element"
            :debug="debug"
            @change="(...arr) => elementChange(element, ...arr)"
          />
        </a-form-model-item>

        <a-divider v-if="element.divider" />
      </div>
    </a-form-model>

    <template v-if="debug">
      <pre>{{ formInline }}</pre>
    </template>
  </a-modal>
</template>

<script>
/*
after function(this, formInline ) 页面显示初始化后执行函数每次显示都执行
func  页面传递回调函数 { key:  () => {} }
itemHide 隐藏表单
  {
    key: value,
  }
item 子项说明
	key		string	数据项key
	label	string	左侧描述，可为空
  wrapper bool	是否与输入框对齐
  divider bool	是否有一个隔离线
	required	bool	是否必填项，如果type 不是 array space 系统自动要求必填
	style	object	除width外的样式
	width	string	长度

	showIf	object	满足里面所有项才显示， undefined 不启动判断
	hideIf	object	满足里面所有项才隐藏， undefined 不启动判断

	type	show
		内容		value 值
		key		可为空
	type	editor
		富文本编辑器å
	type	upload-image
    上传一张图片
    data 图片默认值
	type	upload-list
		上传多个文件
    data 文件列表默认值 数组

	扩展子项
		radio	bool 	是否单选， 单选string或number  多选 数组
		change (formInline, value, extData, this) => {}
				this为编辑器的主体， 以下一样

		type	select
			下啦选择
			selectArray	array 	下来数据 {value: "值", label: "标题"}

		type	radio
			buttonStyle		radio类型	风格样式，目前有描边和填色两种风格	outline | solid
			radioArray	array 	下来数据 {value: "值", label: "标题"}

		type	checkbox
			checkboxArray	array 	下来数据 {value: "值", label: "标题"}

		type	switch
			checkedLabel	string 	开启时候的文本描述
			unCheckedLabel	string 	关闭时候的文本描述

		type	number
			number	{min:最小值数字, max: 最大值数字}	数字区间限制

		type	textarea
			autoSize number		默认行

		type	systemArea
			systemArea {
				table: 表,
				field: 字段,
        code: 编码,
				disabled: 是否可选
			}
			selected	bool	为空时自动选择第一个

		type	admin-select

		type	data-select
			searchMap	object	查询条件
			url			string	获取数据url
			init		function 初始化显示数据  返回 [{ value:值, label:显示内容, data:数据对象}]
			selected	bool	为空时自动选择第一个

    type  date-picker
      disabledDate Function disabledDate(current) {
        // Can not select days before today and today
        return current && current < moment().endOf('day');
      },

    type  range-picker
    type  tooltip

  type	array
    array  子项数组
    每个子项里面的value为添加新子项的model， 也可以添加完后在执行中初始化  key + "_model_add" 修改子项的初始值
    value 为初始值  数组  [object]

  type	space
    space  子项数组
    子项增加 button

	type	hidden
		隐藏表单传递
*/
import fileApi from "@/api/file"

export default {
  components: {
    edit: () => import("./edit"),
    draggable: () => import("vuedraggable"),
  },
  model: {
    prop: "visible",
    event: "close",
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    debug: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: "修改资料",
    },
    item: {
      type: Object,
      default: () => {
        return undefined
      },
    },
    itemHide: {
      type: Object,
      default: () => {
        return undefined
      },
    },
    all: {
      type: Boolean,
      default: false,
    },
    width: {
      type: [String, Number],
      default: 400,
    },
    update: {
      type: Function,
      default: () => {},
    },
    after: {
      type: Function,
      default: () => {},
    },
    func: {
      type: Object,
      default: () => {
        return undefined
      },
    },
    labelCol: {
      type: Object,
      default: () => {
        return { span: 4 }
      },
    },
    wrapperCol: {
      type: Object,
      default: () => {
        return { span: 20 }
      },
    },
    callback: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  data() {
    return {
      confirmLoading: false,
      itemKeyOld: "",
      itemKey: "default",
      labelWrapperCol: {
        // span: this.wrapperCol.span,
        offset: this.labelCol.span,
      },
      uploadImage: {
        loading: {},
        change: {},
        one: {},
        list: {},
      },
      rules: {},
      formInline: {},
      formInlineObj: {},
    }
  },
  watch: {
    visible: function () {
      if (!this.visible) return
      this.itemKey = this.$md5(JSON.stringify(this.item))
      if (this.itemKeyOld == this.itemKey) return
      this.itemKeyOld = this.itemKey
      this.pageInit()
    },
  },
  methods: {
    reset() {
      this.$set(this, "formInline", {})
      this.$set(this, "formInlineObj", {})
      this.$set(this, "rules", {})
      this.$set(this, "uploadImage", {
        loading: {},
        change: {},
        one: {},
        list: {},
      })
    },
    pageInit() {
      this.reset()

      for (let k in this.callback) {
        this.$store.commit("setCallback", {
          key: k,
          func: (data) => {
            try {
              this.callback[k](data, this.formInline)
            } catch (e) {
              console.log(e)
            }
          },
        })
      }

      if (this.itemHide) {
        for (let key in this.itemHide) {
          this.$set(this.formInlineObj, key, this.itemHide[key])
          this.$set(this.formInline, key, this.itemHide[key])
        }
      }

      for (let ii in this.item) {
        let element = this.item[ii]
        if (element.type == "space") {
          for (let ii in element.space) {
            this.setItem(element.space[ii])
          }
          continue
        }
        if (element.type == "array") {
          this.setArrayItem(element)
          continue
        }
        this.setItem(element)
      }
      if (this.after) {
        this.after(this, this.formInline)
      }
    },
    setItem(element) {
      if (!element.key) return

      this.$set(this.formInlineObj, element.key, element)

      if (Object.prototype.hasOwnProperty.call(element, "value")) {
        this.$set(this.formInline, element.key, element.value)
      }

      if (!Object.prototype.hasOwnProperty.call(this.formInline, element.key)) {
        this.$set(this.formInline, element.key, element.value)
      }

      if (Object.prototype.hasOwnProperty.call(element, "rules")) {
        this.$set(this.rules, element.key, element.rules)
      }

      if (element.type === "upload-image" || element.type === "upload-list") {
        this.$set(this.uploadImage.loading, element.key, false)
        this.$set(
          this.uploadImage.change,
          element.key,
          element.change
            ? element.change
            : (itemData, itemKey) => {
                console.log(itemKey, itemData)
              }
        )

        if (element.type === "upload-image") {
          this.$set(this.uploadImage.one, element.key, element.data)
        }

        if (element.type === "upload-list") {
          let dataTmpArr = []
          if (element.data && this.$func.isArray(element.data)) {
            dataTmpArr = element.data
          }
          this.$set(this.uploadImage.list, element.key, dataTmpArr)
        }
      }
    },
    setArrayItem(element) {
      this.$set(this.formInlineObj, element.key, element)
      this.$set(this.formInline, element.key, [])
      this.$set(this.formInline, element.key + "_model_add", {})
      var objTmp = {}
      if (!element.value) {
        this.$set(element, "value", [])
      }

      for (let jj in element.value) {
        objTmp = {
          ...element.value[jj],
        }
        for (let jjTMP in element.array) {
          if (
            !Object.prototype.hasOwnProperty.call(
              objTmp,
              element.array[jjTMP]["key"]
            )
          ) {
            objTmp[element.array[jjTMP]["key"]] = undefined
          }
        }

        this.formInline[element.key].push(objTmp)
      }
      for (let jjTMP in element.array) {
        this.$set(
          this.formInline[element.key + "_model_add"],
          element.array[jjTMP]["key"],
          element.array[jjTMP]["value"]
        )

        this.$set(this.formInlineObj, element.key, element)
      }
    },
    showIf(element) {
      if (element.type === "hidden") return false

      let flag = true
      if (element.showIf) {
        let tmp = false
        for (let ii in element.showIf) {
          if (this.formInline[ii] != element.showIf[ii]) {
            tmp = true
          }
          if (tmp) break
        }
        flag = tmp == false
      }
      if (element.hideIf) {
        let tmp = false
        for (let ii in element.hideIf) {
          if (this.formInline[ii] != element.hideIf[ii]) {
            tmp = true
          }
          if (tmp) break
        }
        flag = !(tmp == false)
      }

      return flag
    },
    handleSubmit(e) {
      e.preventDefault()
      let flag = false
      this.$refs.formInline.validate((valid) => {
        flag = valid
      })
      if (!flag) {
        this.$message.warning("请您正确输入信息")
        return false
      }

      let formInline = {}
      if (this.all) {
        formInline = this.formInline
      } else {
        flag = false

        if (this.itemHide) {
          for (let key in this.itemHide) {
            if (Object.prototype.hasOwnProperty.call(this.formInline, key)) {
              if (this.formInline[key] !== this.itemHide[key]) {
                formInline[key] = this.formInline[key]
                flag = true
              }
            }
          }
        }

        for (let ii in this.item) {
          const element = this.item[ii]
          if (element.type == "space") {
            if (element.space)
              for (let jj in element.space) {
                if (
                  Object.prototype.hasOwnProperty.call(
                    this.formInline,
                    element.space[jj].key
                  )
                ) {
                  if (
                    this.formInline[element.space[jj].key] !==
                    element.space[jj].value
                  ) {
                    formInline[element.space[jj].key] = this.formInline[
                      element.space[jj].key
                    ]
                    flag = true
                  }
                }
              }
            continue
          }
          if (element.type == "upload-list") {
            formInline[element.key] = this.formInline[element.key]
            flag = true
            continue
          }

          if (
            Object.prototype.hasOwnProperty.call(this.formInline, element.key)
          ) {
            if (this.formInline[element.key] !== element.value) {
              formInline[element.key] = this.formInline[element.key]
              flag = true
            }
          }
        }
        if (!flag) {
          this.$message.warning("未有任何修改")
          return false
        }
      }

      this.confirmLoading = true
      this.update(formInline, (rtFlag) => {
        this.confirmLoading = false
        if (rtFlag) {
          this.onClose()
        }
      })
    },
    elementChange(element, val, ext) {
      if (element.change) element.change(this.formInline, val, ext, this)
    },
    elementArrayChange(element, key, index, val, ext) {
      if (element.change)
        element.change(
          this.formInline,
          this.formInline[key][index],
          val,
          ext,
          this
        )

      if (this.item[key] && this.item[key].change)
        this.item[key].change(this.formInline, key, this)
    },
    resetArrayItem(key, dataObj) {
      this.formInline[key + "_model_add"] = {
        ...this.formInline[key + "_model_add"],
        ...dataObj,
      }
    },
    addArrayItem(key, dataObj) {
      if (!Object.prototype.hasOwnProperty.call(this.formInline, key)) {
        this.$set(this.formInline, key, [])
      }
      this.formInline[key].push({
        ...this.formInline[key + "_model_add"],
        ...dataObj,
      })
      if (this.item[key] && this.item[key].change)
        this.item[key].change(this.formInline, key, this)
    },
    deleteArrayItem(element, index) {
      if (index >= this.formInline[element.key].length) return
      this.formInline[element.key].splice(index, 1)
      if (this.item[element.key] && this.item[element.key].change)
        this.item[element.key].change(this.formInline, element.key, this)
    },
    onClose() {
      this.$emit("close", false)
      this.$emit("cancel")
    },
    btnClick(elementSec) {
      if (elementSec.click) elementSec.click(this.formInline, elementSec, this)
    },
    changeDataSearchMap() {},
    //图片文件
    handleMouseEnter(e) {
      e.target.querySelector(".img-view-operate").style.display = "flex"
    },
    handleMouseLeave(e) {
      e.target.querySelector(".img-view-operate").style.display = "none"
    },
    beforeImageUpload(file) {
      const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png"
      if (!isJpgOrPng) {
        this.$message.error("请选择jpg或png的图片!")
      }
      const isFileSize = file.size / 1024 / 1024 < 5
      if (!isFileSize) {
        this.$message.error("上传文件最大5M")
      }
      return isJpgOrPng && isFileSize
    },
    handleImageChange(info, itemKey) {
      if (info.file.status === "uploading") {
        this.$set(this.uploadImage.loading, itemKey, true)
        return
      }
      if (info.file.status === "error") {
        this.$set(this.uploadImage.loading, itemKey, false)
        return
      }
      if (info.file.status === "done") {
        this.$set(this.uploadImage.loading, itemKey, false)

        const response = info.file.response
        if (response.code !== 1) {
          this.$message.warning(response.message)
          return
        }
        this.$message.success(response.message)

        if (
          this.uploadImage.one[itemKey] &&
          this.uploadImage.one[itemKey].save_file
        ) {
          fileApi.delete(this.uploadImage.one[itemKey].save_file)
        }

        this.$set(this.uploadImage.one, itemKey, response.data)
        this.$set(this.formInline, itemKey, response.data.save_file)
        if (this.uploadImage.change[itemKey])
          this.uploadImage.change[itemKey](this.formInline, response.data)

        return
      }
    },

    //文件管理
    handleFileChange(info, itemKey) {
      if (info.file.status === "uploading") {
        this.$set(this.uploadImage.loading, itemKey, true)
        return
      }
      if (info.file.status === "error") {
        this.$set(this.uploadImage.loading, itemKey, false)
        return
      }
      if (info.file.status === "done") {
        this.$set(this.uploadImage.loading, itemKey, false)

        const response = info.file.response
        if (response.code !== 1) {
          this.$message.warning(response.message)
          return
        }
        this.$message.success(response.message)

        if (
          !Object.prototype.hasOwnProperty.call(this.uploadImage.list, itemKey)
        ) {
          this.$set(this.uploadImage.list, itemKey, [])
        }

        if (
          !Object.prototype.hasOwnProperty.call(this.formInline, itemKey) ||
          !this.$func.isArray(this.formInline[itemKey])
        ) {
          this.$set(this.formInline, itemKey, [])
        }

        this.formInline[itemKey].push(response.data.save_file)
        this.uploadImage.list[itemKey].push(response.data)
        if (this.uploadImage.change[itemKey])
          this.uploadImage.change[itemKey](
            this.formInline,
            response.data,
            this.uploadImage.list[itemKey]
          )
        return
      }
    },
    handleDelete(itemKey, index) {
      if (!Object.prototype.hasOwnProperty.call(this.formInline, itemKey)) {
        return
      }
      if (
        !Object.prototype.hasOwnProperty.call(this.uploadImage.list, itemKey)
      ) {
        return
      }

      if (this.uploadImage.list[itemKey][index]) {
        //暂时不删除
        fileApi.delete(this.uploadImage.list[itemKey][index].save_file)
      }

      this.uploadImage.list[itemKey].splice(index, 1)

      let arr = []
      this.uploadImage.list[itemKey].forEach((element) => {
        arr.push(element.url_800)
      })
      this.formInline[itemKey] = arr

      if (this.uploadImage.change[itemKey])
        this.uploadImage.change[itemKey](
          this.formInline,
          undefined,
          this.uploadImage.list[itemKey]
        )
    },
  },
}
</script>

<style lang="less" type="text/less" scoped>
.ant-form-item {
  margin-bottom: 6px;
}
.imgDiv {
  height: 104px;
  width: 104px;
  background: #f7f7f7;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  img {
    width: 100%;
    min-width: 104px;
  }
  .img-view-operate {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    display: none;
    justify-content: space-around;
    align-items: center;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    i {
      display: inline-block;
      font-size: 30px;
      color: #fff;
      font-weight: 800;
    }
  }
}
.handle {
  cursor: move;
}
.ghost {
  opacity: 0.5;
  background: #c8ebfb !important;
}
</style>
